home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 145
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin
/
games
/
spassion
/
source.lzh
/
SOURCE
/
ENEMY.C
< prev
next >
Wrap
Text File
|
2000-03-30
|
11KB
|
445 lines
/*
#include <stdio.h>
#include <iocslib.H>
#include <XSP2lib.H>
*/
/*short deb=0;*/
/*
* enemy & eshot functions
*/
#include "SPASSION.H"
#include "PLAYER.H"
#include "SHOT.H"
#include "ENEMY.H"
#include "ENTRY.H"
#include "SOUND.H"
#include "SUB.H"
#ifndef NULL
#define NULL ((void *) 0)
#endif
#define FLUSH_MAX 1 /* ダメージで光る時間 */
#define ENEMY_MAX 128 /* 画面上に出る敵の数 */
#define PLAYER_DAMAGE 2 /* プレイヤー無敵時に体当たりで与えるダメージ */
#define PLAYER_OPTION_DAMAGE 1 /* オプションの体当たりで与えるダメージ */
static ENEMY enemy[ ENEMY_MAX ];
/* enemy_alloc()用 */
static ENEMY *enemy_free,
*enemy_top;
/* FuncEnemy/ 以下の敵移動ルーチン */
void InitEnemyZako00(ENEMY *);
void InitEnemyZako01(ENEMY *);
void InitEnemyZako02(ENEMY *);
void InitEnemyZako03(ENEMY *);
void InitEnemyZako04(ENEMY *);
void InitEnemyZako05(ENEMY *);
void InitEnemyHatch(ENEMY *ene);
void InitEnemyBattery(ENEMY *ene);
void InitEnemyVolcano(ENEMY *ene);
void InitEnemyRock(ENEMY *ene);
void InitEnemyMine(ENEMY *ene);
void InitEnemyCrystal_L(ENEMY *ene);
void InitEnemyCrystal_M(ENEMY *ene);
void InitEnemyCrystal(ENEMY *ene);
void InitEnemyBubble_L(ENEMY *ene);
void InitEnemyBubble(ENEMY *ene);
void InitEnemyBrain(ENEMY *ene);
void InitEnemyBossM00(ENEMY *);
void InitEnemyBossM01(ENEMY *);
void InitEnemyDragonHead(ENEMY *);
void InitEnemyDragonBody(ENEMY *);
void InitEnemyBoss01(ENEMY *);
void InitEnemyBoss02(ENEMY *);
void InitEnemyBoss03(ENEMY *);
void InitEnemyBoss04(ENEMY *);
void InitEnemyLBoss(ENEMY *);
void InitEnemyBossArm(ENEMY *);
void InitEnemyBossArm1(ENEMY *);
void InitEnemyCore(ENEMY *ene);
void InitEnemyShield(ENEMY *ene);
void InitEnemyLCore(ENEMY *);
void InitEnemyLBattery1(ENEMY *);
void InitEnemyLBattery2(ENEMY *);
void InitEnemyLBattery3(ENEMY *);
void InitItem(ENEMY *ene);
void InitEnemyZako00Hit( void );
void InitEnemyZako01Hit( void );
void InitEnemyZako02Hit( void );
void InitEnemyZako03Hit( void );
void InitEnemyZako04Hit( void );
void InitEnemyZako05Hit( void );
void InitEnemyHatchHit( void );
void InitEnemyBatteryHit( void );
void InitEnemyVolcanoHit( void );
void InitEnemyRockHit( void );
void InitEnemyMineHit( void );
void InitEnemyCrystal_LHit( void );
void InitEnemyCrystal_MHit( void );
void InitEnemyCrystalHit( void );
void InitEnemyBubble_LHit( void );
void InitEnemyBubbleHit( void );
void InitEnemyBrainHit( void );
void InitEnemyBossM00Hit( void );
void InitEnemyBossM01Hit( void );
void InitEnemyDragonHeadHit( void );
void InitEnemyDragonBodyHit( void );
void InitEnemyBoss01Hit( void );
void InitEnemyBoss02Hit( void );
void InitEnemyBoss03Hit( void );
void InitEnemyBoss04Hit( void );
void InitEnemyLBossHit( void );
void InitEnemyBossArmHit( void );
void InitEnemyBossArm1Hit( void );
void InitEnemyCoreHit( void );
void InitEnemyShieldHit( void );
void InitEnemyLCoreHit( void );
void InitEnemyLBattery1Hit( void );
void InitEnemyLBattery2Hit( void );
void InitEnemyLBattery3Hit( void );
void InitItemHit( void );
typedef void (*func_init) (struct ENEMY *);
func_init FuncEnemyInit[]=
{
InitEnemyZako00,
InitEnemyZako01,
InitEnemyZako02,
InitEnemyZako03,
InitEnemyZako04,
InitEnemyZako05,
InitEnemyHatch,
InitEnemyBattery,
InitEnemyVolcano,
InitEnemyRock,
InitEnemyMine,
InitEnemyCrystal_L,
InitEnemyCrystal_M,
InitEnemyCrystal,
InitEnemyBubble_L,
InitEnemyBubble,
InitEnemyBrain,
InitEnemyBossM00,
InitEnemyBossM01,
InitEnemyDragonHead,
InitEnemyDragonBody,
InitEnemyBoss01,
InitEnemyBoss02,
InitEnemyBoss03,
InitEnemyBoss04,
InitEnemyLBoss,
InitEnemyBossArm,
InitEnemyBossArm1,
InitEnemyCore,
InitEnemyShield,
InitEnemyLCore,
InitEnemyLBattery1,
InitEnemyLBattery2,
InitEnemyLBattery3,
InitItem,
};
typedef void (*func_init_hit) (void);
func_init_hit FuncEnemyHitInit[]=
{
InitEnemyZako00Hit,
InitEnemyZako01Hit,
InitEnemyZako02Hit,
InitEnemyZako03Hit,
InitEnemyZako04Hit,
InitEnemyZako05Hit,
InitEnemyHatchHit,
InitEnemyBatteryHit,
InitEnemyVolcanoHit,
InitEnemyRockHit,
InitEnemyMineHit,
InitEnemyCrystal_LHit,
InitEnemyCrystal_MHit,
InitEnemyCrystalHit,
InitEnemyBubble_LHit,
InitEnemyBubbleHit,
InitEnemyBrainHit,
InitEnemyBossM00Hit,
InitEnemyBossM01Hit,
InitEnemyDragonHeadHit,
InitEnemyDragonBodyHit,
InitEnemyBoss01Hit,
InitEnemyBoss02Hit,
InitEnemyBoss03Hit,
InitEnemyBoss04Hit,
InitEnemyLBossHit,
InitEnemyBossArmHit,
InitEnemyBossArm1Hit,
InitEnemyCoreHit,
InitEnemyShieldHit,
InitEnemyLCoreHit,
InitEnemyLBattery1Hit,
InitEnemyLBattery2Hit,
InitEnemyLBattery3Hit,
InitItemHit,
};
/*
* 敵・敵弾・データの初期化
*/
void InitEnemy( void )
{
short i;
enemy_top = NULL;
enemy_free = enemy;
for( i = 0; i < ENEMY_MAX; i++ ){
enemy[i].next = &enemy[i + 1];
enemy[i].pre = &enemy[i - 1];
}
enemy[ 0 ].pre = NULL;
enemy[ENEMY_MAX - 1].next = NULL;
}
/*
* 敵・敵弾・当たり判定データの初期化
* 起動時に一度だけ使う
*/
void InitEnemyHit( void )
{
short type;
for(type=0;type<=ITEM;type++){
FuncEnemyHitInit[type]();/* 初期化ルーチンへ飛ぶ(関数へのポインタってヤツ) */
}
}
/*
* 敵出現時に呼ばれる
*/
ENEMY *MakeEnemy(short type, signed short x, signed short y,
short arg, struct ENEMY *parent)
{
ENEMY *ene;
/* 空いているか調べる */
if ( !enemy_free ) return (ENEMY *)0;
/* 空いているのを探す */
ene = enemy_free;
enemy_free = ene->next;
/* 使っているリストに入れる */
if( ene->next = enemy_top ){
enemy_top->pre = ene;
}
ene->pre = 0;
enemy_top = ene;
/* 各種設定 */
ene->lx = x << 16;
ene->ly = y << 16;
ene->type = type;
ene->arg = arg;
ene->damage = 0;
ene->damage_kind = 0;
ene->count = 0;
ene->dead_count = 0;
ene->flush_count = 0;
ene->anim_count = 0;
ene->state = 0;
ene->angle = 0;
ene->flg = 0;
ene->parent = parent;
ene->child_kill = ene->child_death = 0;
FuncEnemyInit[type](ene);/* 初期化ルーチンへ飛ぶ(関数へのポインタってヤツ) */
return(ene); /* 作成したワークへのポインタを返す */
}
/*
* 敵移動メイン
*/
void MoveEnemy( void )
{
PLAYER *pl;
SHOT *shot = shot_top; /* 現在注目しているショットのワーク */
ENEMY *ene;
short hit_flag=0;
ene = enemy_top; /* 現在注目しているワーク */
while( ene ){
#ifdef DEBUG
if( !ene->func_enemy_move ){ /* 敵の移動ルーチンがない? */
void game_end( void );
printf("MoveEnemy 1\n");
key_wait();
game_end();
}
#endif
if ( !( *( ene->func_enemy_move ) )( ene ) ) { /* 敵を移動させる */
ene=EraseEnemy( ene );
} else { /* 消滅していない時 */
signed short pl_x,pl_y,i,j,k;
signed short hitp_x1,hitp_x2,hitp_y1,hitp_y2;
signed short hito_x1,hito_x2,hito_y1,hito_y2;
signed short hits_x1,hits_x2,hits_y1,hits_y2;
/* D キーで当たり判定をしない(デバッグ用) */
/*#ifdef DEBUG*/
#if 0
{
if( BITSNS(0x04) & BIT(0) ){
while( BITSNS(0x04) & BIT(0) );
if(deb)deb=0;
else deb=1;
}
/*
if(deb){
ene = ene->next;
continue;
}
*/
}
#endif
for( k=0;ene->hit_p[k];k++ ){
hitp_x1 = ENE_X+ene->hit_p[k]->x1;hitp_y1 = ENE_Y+ene->hit_p[k]->y1;
hitp_x2 = ENE_X+ene->hit_p[k]->x2;hitp_y2 = ENE_Y+ene->hit_p[k]->y2;
hito_x1 = ENE_X+ene->hit_o[k]->x1;hito_y1 = ENE_Y+ene->hit_o[k]->y1;
hito_x2 = ENE_X+ene->hit_o[k]->x2;hito_y2 = ENE_Y+ene->hit_o[k]->y2;
hits_x1 = ENE_X+ene->hit_s[k]->x1;hits_y1 = ENE_Y+ene->hit_s[k]->y1;
hits_x2 = ENE_X+ene->hit_s[k]->x2;hits_y2 = ENE_Y+ene->hit_s[k]->y2;
for( i=0,pl=&player[0];i<=play_mode;i++,pl++ ){
/* プレイヤーとの当たり判定 */
/* プレイヤーは一度敵に当たったら、そのターンは他の敵とは判定しない
そうしないと触れていない泡に当たっていることになってしまう*/
if( !hit_flag ){
pl_x=pl->x+5;
pl_y=pl->y;
if( hitp_x1 < pl_x ){
if( hitp_x2 > pl_x ){
if( hitp_y1 < pl_y ){
if( hitp_y2 > pl_y ){
#if 1
/* if(!deb){*/
if( !ene->no_dead ){
if( pl->state == PLAYER_ALIVE ){
if( !pl->muteki_count )
pl->state = PLAYER_DEAD; /* プレイヤー撃破 */
}
}
/* }*/
#endif
hit_flag=1;
ene->damage += PLAYER_DAMAGE;
ene->player=pl; /* ダメージを与えたプレイヤー */
ene->damage_kind=PLAYER_ATTACK; /* 体当たり */
#if 0
B_CLR_AL();
printf("PLAYER_HIT!! %d \n",k);
printf("i=%d px=%d py=%d \n",i,pl->x+5,pl->y);
printf("e_x=%d e_x1=%d e_x2=%d \n",ENE_X,ene->hit_p[k]->x1,ene->hit_p[k]->x2);
printf("e_y=%d e_y1=%d e_y2=%d \n",ENE_Y,ene->hit_p[k]->y1,ene->hit_p[k]->y2);
xsp_out();
key_wait();
#endif
}}}}
}
/* オプションとの当たり判定 */
for( j=0;j<2;j++ ){
signed short option_w;
if( hito_x1 <= (option_w = *((short *) (&pl->option[j].lx))) ){
if( hito_x2 >= option_w ){
if( hito_y1 <= (option_w = *((short *) (&pl->option[j].ly))) ){
if( hito_y2 >= option_w ){
#if 0
B_CLR_AL();
printf("OPTION_HIT!! %d \n",k);
printf("j=%d op_x=%d op_y=%d \n",j,pl->option[j].lx>>16,pl->option[j].ly>>16);
printf("e_x=%d e_x1=%d e_x2=%d \n",ENE_X,hito_x1,hito_x2);
printf("e_y=%d e_y1=%d e_y2=%d \n",ENE_Y,hito_y1,hito_y2);
xsp_out();
key_wait();
#endif
ene->damage += PLAYER_OPTION_DAMAGE;
ene->player=pl; /* ダメージを与えたプレイヤー */
ene->damage_kind=OPTION_ATTACK; /* オプションの体当たり */
}}}}
}
}
/* ショットとの当たり判定 */
for( shot = shot_top; shot; ){
signed short shot_w;
if( (hits_x1-shot->hit_x) <= (shot_w=SHOT_X) ){
if( (hits_x2+shot->hit_x) >= shot_w ){
if( (hits_y1-shot->hit_y) <= (shot_w=SHOT_Y) ){
if( (hits_y2+shot->hit_y) >= shot_w ){
#if 0
B_CLR_AL();
printf("SHOT_HIT!! %d \n",k);
printf("sx=%d sy=%d hx=%d hy=%d \n",SHOT_X,SHOT_Y,shot->hit_x,shot->hit_y);
printf("ex=%d ey=%d \n",ENE_X,ENE_Y);
printf("ehx1=%d ehx2=%d ehy1=%d ehy2=%d \n",
ene->hit_s[k]->x1,ene->hit_s[k]->x2,
ene->hit_s[k]->y1,ene->hit_s[k]->y2);
printf("ex1=%d ex2=%d ey1=%d ey2=%d \n",
hits_x1,hits_x2,hits_y1,hits_y2);
printf("ehx1=%d ehx2=%d ehy1=%d ehy2=%d \n",
hits_x1-shot->hit_x,hits_x2+shot->hit_x,
hits_y1-shot->hit_y,hits_y2+shot->hit_y);
xsp_out();
OutBox();
key_wait();
#endif
if(!shot->penetration)
shot->damage = !0; /* そのショットを使えなくする */
ene->damage += shot->pow;
/* ene->damage += shot_damage[shot->frame];*/
ene->damage_kind=SHOT_ATTACK; /* ショット */
}}}}
shot = shot->next;
}
}
ene = ene->next;
}
}
}
/*
* 敵消滅
*/
ENEMY *EraseEnemy( ENEMY *ene )
{
ENEMY *next;
next = ene->next;
ene->type = 0;
/* 使っているリストから抜く */
if ( ene->pre ) {
ene->pre->next = ene->next;
if ( ene->next ) ene->next->pre = ene->pre;
} else {
if ( ene->next ) ene->next->pre = 0;
enemy_top = ene->next;
}
/* 空いているリストに入れる */
ene->pre = 0;
ene->next = enemy_free;
enemy_free = ene;
return next;
}